package com.adt.studioms.web.controller.user;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.springframework.validation.BindException;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;

import com.adt.studioms.StudiomsApplication;
import com.adt.studioms.api.PaymentTxAPI;
import com.adt.studioms.om.PaymentTx;
import com.adt.studioms.om.PaymentTxDetail;
import com.asao.baseware.core.security.ITrustedPassport;
import com.asao.baseware.core.util.DateUtil;
import com.asao.baseware.core.web.controller.EntityCommand;
import com.asao.baseware.core.web.controller.EntityFormController;

public class PaymentTxController extends EntityFormController<PaymentTxCommand> {
    PaymentTxAPI ptxAPI;

    class PaymentTxValidator implements Validator {

        public boolean supports(Class clazz) {
            return clazz.equals(PaymentTxCommand.class);
        }

        public void validate(Object target, Errors errors) {
            PaymentTxCommand cmd = (PaymentTxCommand) target;
            
            if (StringUtils.isBlank(cmd.getPaymentReason())) {
                errors.rejectValue("paymentReason", "paymentTx.reasonIsRequired", "Reason is required");
            }
            
            if (StringUtils.isNotBlank(cmd.getReceiptDate())) {
                if (cmd.receiptDate()==null) {
                    errors.rejectValue("receiptDate", "paymentTx.receiptDateIsNotValid", "Receipt Date is not valid");
                }
            }
            
            if (StringUtils.isBlank(cmd.getAmount())) {
                errors.rejectValue("amount", "paymentTx.amountIsRequired", "Amount is required");
            } else {
                if (!NumberUtils.isNumber(cmd.getAmount())) {
                    errors.rejectValue("amount", "paymentTx.amountIsNotValid", "Amount is not valid");
                }
            }
        }

    }

    public PaymentTxController() {
        super();
        ptxAPI = StudiomsApplication.instance.getApiRegistry().lookupAPI(ITrustedPassport.instance, PaymentTxAPI.class);

        setCommandClass(PaymentTxCommand.class);
        setValidator(new PaymentTxValidator());
    }

    protected void publishEntity(long id, PaymentTxCommand command) {
        PaymentTx ptx = ptxAPI.get(id);
        if (ptx!=null) {
            PaymentTxDetail ptxd = ptx.getDetail();
            command.setId(ptx.getId());
            command.setPayer(ptx.getPayer());
            command.setReceiptNumber(ptx.getReceiptNumber());
            if (ptx.getPaymentDate()!=null) {
                String pd = new SimpleDateFormat("dd/MM/yyyy").format(ptx.getFormattedPaymentDate());
                command.setPaymentDate(pd);
            }
            if (ptx.getReceiptDate()!=null) {
                String rd = new SimpleDateFormat("dd/MM/yyyy").format(ptx.getFormattedReceiptDate());
                command.setReceiptDate(rd);
            }
            command.setAmount(ptxd.getAmount()+"");
            command.setPaymentReason(ptxd.getDescription());
        }
    }

    protected void createEntity(PaymentTxCommand command, BindException errors) {
        PaymentTx ptx = ptxAPI.createPaymentTx(null, 
                                               command.paymentDate(), 
                                               command.getPaymentReason(), 
                                               command.amount(), 
                                               command.getReceiptNumber(), 
                                               command.receiptDate(), 
                                               command.getPayer());
        command.setId(ptx.getId());
    }

    protected void updateEntity(PaymentTxCommand command, BindException errors) {
        PaymentTx ptx = ptxAPI.get(command.getId());
        if (ptx!=null) {
            PaymentTxDetail ptxd = ptx.getDetail();
            ptx.setPayer(command.getPayer());
            ptx.setReceiptNumber(command.getReceiptNumber());
            ptx.setPaymentDate(command.paymentDate());
            ptx.setReceiptDate(command.receiptDate());
            ptxd.setAmount(command.amount());
            ptxd.setDescription(command.getPaymentReason());
            ptxAPI.update(ptx);
        }
    }

    protected void deleteEntity(PaymentTxCommand command, BindException errors) {
        ptxAPI.delete(command.getId());
    }
}

class PaymentTxCommand extends EntityCommand {
    String paymentDate;
    String payer;
    String receiptNumber;
    String receiptDate;
    String paymentReason;
    String amount;

    public PaymentTxCommand() {
        paymentDate = new SimpleDateFormat("dd/MM/yyyy").format(new Date());
        receiptDate = paymentDate;
    }
    
    public String getPaymentDate() {
        return paymentDate;
    }
    
    public Long paymentDate() {
        Date date = DateUtil.parseDate(paymentDate);
        return date!=null ? date.getTime() : null;
    }

    public void setPaymentDate(String paymentDate) {
        this.paymentDate = paymentDate;
    }

    public String getPayer() {
        return payer;
    }

    public void setPayer(String payer) {
        this.payer = payer;
    }

    public String getReceiptNumber() {
        return receiptNumber;
    }

    public void setReceiptNumber(String receiptNumber) {
        this.receiptNumber = receiptNumber;
    }

    public String getReceiptDate() {
        return receiptDate;
    }
    
    public Long receiptDate() {
        Date date = DateUtil.parseDate(receiptDate);
        return date!=null ? date.getTime() : null;
    }

    public void setReceiptDate(String receiptDate) {
        this.receiptDate = receiptDate;
    }

    public String getPaymentReason() {
        return paymentReason;
    }

    public void setPaymentReason(String paymentReason) {
        this.paymentReason = paymentReason;
    }

    public String getAmount() {
        return amount;
    }
    
    public Long amount() {
        return NumberUtils.toLong(amount);
    }

    public void setAmount(String amount) {
        this.amount = amount;
    }
}